package com.btpn.custody.service.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.btpn.custody.bean.ParameterBeans;
import com.btpn.custody.common.Constant;
import com.btpn.custody.dao.IArea;
import com.btpn.custody.dao.IBranch;
import com.btpn.custody.dao.IDownloadLog;
import com.btpn.custody.dao.IMasterData;
import com.btpn.custody.dao.IRegion;
import com.btpn.custody.dao.ITL_GLOBAL;
import com.btpn.custody.entity.Area;
import com.btpn.custody.entity.Branch;
import com.btpn.custody.entity.MasterData;
import com.btpn.custody.entity.Region;
import com.btpn.custody.entity.TL_GLOBAL;
import com.btpn.custody.service.IGlobalService;
import com.btpn.custody.web.m001.model.BranchModel;

@Service("globalService")
@Transactional
public class GlobalServiceImpl implements IGlobalService {

	@Autowired
	private IArea areaDaoHibernate;
	
	@Autowired
	private IBranch branchDaoHibernate;

	@Autowired
	private IDownloadLog downloadLogDaoHibernate;
	
	@Autowired
	private IRegion regionDaoHibernate;
	
	@Autowired
	private ITL_GLOBAL TL_GLOBAL_DaoHibernate;
	
	@Autowired
	private ParameterBeans parameterBeans;
	
	@Autowired
	private IMasterData masterDataDaoHibernate;
	
	@Override
	public void createOrUpdateRegion(Long regionId, String regionCode, String regionName, String user) {

		Region theRegion = regionDaoHibernate.get(regionId);		// update
		if (theRegion == null) {
			theRegion = new Region();								// create
			theRegion.setCode(regionCode);
			theRegion.setName(regionName);
			theRegion.setCreatedBy(user);
			Serializable id = regionDaoHibernate.create(theRegion);
			
			TL_GLOBAL_DaoHibernate.create(Region.class.getName(), Constant.ACTION__CREATE, TL_GLOBAL.GROUP_1, user, "ID:" + id);
		} else {
			// when update, regionCode ga di-set untuk menghindari kemungkinan error duplicate (karena code is unique)
			theRegion.setName(regionName);
			theRegion.setUpdatedDate(new Date());
			theRegion.setUpdatedBy(user);
	
			TL_GLOBAL_DaoHibernate.create(Region.class.getName(), Constant.ACTION__UPDATE, TL_GLOBAL.GROUP_1, user, "ID:" + theRegion.getId());
		}
	}
	
	@Override
	public void deleteRegions(Long[] regionIds, String user) {
		
		if (regionIds != null) {
			for (int i = 0; i<regionIds.length; i++) {
				regionDaoHibernate.delete(regionIds[i]);
				
				TL_GLOBAL_DaoHibernate.create(Region.class.getName(), Constant.ACTION__DELETE, TL_GLOBAL.GROUP_1, user, "ID:" + regionIds[i]);
			}
		}
	}

	@Override
	public void createOrUpdateArea(Long areaId, String areaCode, String areaName, Long regionId, Boolean isJkt, String user) {

		Area theArea = areaDaoHibernate.get(areaId);		// update
		if (theArea == null) {
			theArea = new Area();							// create
			theArea.setCode(areaCode);
			theArea.setName(areaName);
			theArea.setJakarta(isJkt);
			theArea.setRegion(regionDaoHibernate.get(regionId));
			theArea.setCreatedBy(user);
			Serializable id = areaDaoHibernate.create(theArea);
			
			TL_GLOBAL_DaoHibernate.create(Area.class.getName(), Constant.ACTION__CREATE, TL_GLOBAL.GROUP_1, user, "ID:" + id);
		} else {
			// when update, areaCode ga di-set untuk menghindari kemungkinan error duplicate (karena code is unique)
			theArea.setName(areaName);
			theArea.setJakarta(isJkt);
			theArea.setRegion(regionDaoHibernate.get(regionId));
			theArea.setUpdatedDate(new Date());
			theArea.setUpdatedBy(user);
	
			TL_GLOBAL_DaoHibernate.create(Area.class.getName(), Constant.ACTION__UPDATE, TL_GLOBAL.GROUP_1, user, "ID:" + theArea.getId());
		}
		
		// refresh areaMap
		parameterBeans.initAreaMap();
	}

	@Override
	public void deleteAreas(Long[] areaIds, String user) {
		if (areaIds != null) {
			for (int i = 0; i<areaIds.length; i++) {
				areaDaoHibernate.delete(areaIds[i]);
				
				TL_GLOBAL_DaoHibernate.create(Area.class.getName(), Constant.ACTION__DELETE, TL_GLOBAL.GROUP_1, user, "ID:" + areaIds[i]);
			}
			
			// refresh areaMap
			parameterBeans.initAreaMap();
		}
	}

	@Override
	public void createOrUpdateBranch(Long branchId, String branchCode, String branchName, String branchEmail, Long areaId, String user) {
		
		Branch theBranch = branchDaoHibernate.get(branchId);		// update
		if (theBranch == null) {
			theBranch = new Branch();								// create
			theBranch.setCode(branchCode);
			theBranch.setName(branchName);
			theBranch.setEmail(branchEmail);
			theBranch.setArea(areaDaoHibernate.get(areaId));
			theBranch.setCreatedBy(user);
			Serializable id = branchDaoHibernate.create(theBranch);
			
			TL_GLOBAL_DaoHibernate.create(Branch.class.getName(), Constant.ACTION__CREATE, TL_GLOBAL.GROUP_1, user, "ID:" + id);
			
			// get MD with status=FAIL & branch=branchCode then set status=NEW
			List<MasterData> masterDatas = masterDataDaoHibernate.findByStatusBranchCode(Constant.STATUS__MD_FAIL, branchCode);
			for (MasterData md : masterDatas) {
				md.setSTATUS_MD(Constant.STATUS__MD_NEW);
			}
		} else {
			// when update, branchCode ga di-set untuk menghindari kemungkinan error duplicate (karena code is unique)
			theBranch.setName(branchName);
			theBranch.setEmail(branchEmail);
			theBranch.setArea(areaDaoHibernate.get(areaId));
			theBranch.setUpdatedDate(new Date());
			theBranch.setUpdatedBy(user);
	
			TL_GLOBAL_DaoHibernate.create(Branch.class.getName(), Constant.ACTION__UPDATE, TL_GLOBAL.GROUP_1, user, "ID:" + theBranch.getId());
		}
	}

	@Override
	public void deleteBranchs(Long[] branchIds, String user) {
		if (branchIds != null) {
			for (int i = 0; i<branchIds.length; i++) {
				branchDaoHibernate.delete(branchIds[i]);
				
				TL_GLOBAL_DaoHibernate.create(Branch.class.getName(), Constant.ACTION__DELETE, TL_GLOBAL.GROUP_1, user, "ID:" + branchIds[i]);
			}
		}
	}

	@Override
	public List<BranchModel> findAllBranchModel() {
		
		List<BranchModel> result = new ArrayList<BranchModel>();
		
		for (Branch b : branchDaoHibernate.findAll()) {
			result.add(new BranchModel(
					b.getId(), b.getCode(), b.getName(), 
					b.getArea().getId(), b.getArea().getName(), 
					b.getArea().getRegion().getId(), b.getArea().getRegion().getName()));
		}
		
		return result;
	}

	@Override
	public String getDownloadLogException(Long id) {

		return downloadLogDaoHibernate.get(id).getException();
	}
}
